﻿using SuperX.Common.Log;
using SuperX.MiddlewareBase;
using RabbitMQ.Client;
using System;
using System.Text;

namespace SuperX.DataCenterService.RabbitMQ.Model
{
    public class RabbitChannel : ChannelBase
    {
        public RabbitChannel(RabbitChannelConfig channelConfig)
        {
            Name = channelConfig.Name;
            TagName = channelConfig.TagName;
            ChannelConfig = channelConfig;
            QueueName = channelConfig.CustomQueueName;
        }

        public RabbitChannelConfig ChannelConfig { get; set; }

        /// <summary>
        /// 队列名称
        /// </summary>
        public string QueueName { get; set; }

        /// <summary>
        /// 主机连接信息
        /// </summary>
        public IConnection Connection
        {
            get
            {
                if (Parent is RabbitHost host)
                {
                    return host.Connection;
                }
                return null;
            }
        }

        /// <summary>
        /// 通道
        /// </summary>
        public IModel Channel { get; set; }

        /// <summary>
        /// 路由
        /// </summary>
        public string RoutingKey { get; set; }

        /// <summary>
        /// 消息属性
        /// </summary>
        private IBasicProperties Properties { get; set; }

        /// <summary>
        /// 交换机名字
        /// </summary>
        public string ExchangeName { get; set; }

        /// <summary>
        /// 创建连接与通道
        /// </summary>
        public override void Connect()
        {
            try
            {
                //创建连接、通道并且设置改角色的属性
                if (string.IsNullOrEmpty(QueueName))
                    QueueName = RoutingKey;
                if (Connection != null && Channel == null)
                {
                    Channel = Connection.CreateModel();
                    Properties = Channel.CreateBasicProperties();
                    Properties.Persistent = ChannelConfig.Durable;
                    DeclareAndBind();
                }
            }
            catch (Exception ex)
            {
                Logger.Error($"{ex.Message}!");
            }
        }

        /// <summary>
        /// 声明交换机、队列并绑定
        /// </summary>
        public void DeclareAndBind()
        {
            try
            {
                switch (Roles)
                {
                    case Roles.Producer:
                        Channel.ExchangeDeclare(ExchangeName, ExchangeType.Topic, false);
                        Channel.QueueDeclare(QueueName, durable: ChannelConfig.Durable, exclusive: ChannelConfig.Exclusive, autoDelete: ChannelConfig.IsAutoDelete, arguments: null);
                        Channel.QueueBind(QueueName, ExchangeName, routingKey: RoutingKey);
                        break;

                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                Logger.ErrorException(ex);
            }
        }

        public override void Publish(string value)
        {
            Channel.BasicPublish(ExchangeName, RoutingKey, Properties, Encoding.UTF8.GetBytes(value));
        }

        public override bool GetSendState()
        {
            return Channel != null && Channel.IsOpen;
        }

        public override void Stop()
        {
            try
            {
                base.Stop();
                Channel?.Close();
                Channel?.Dispose();
            }
            catch (Exception ex)
            {
                Logger.ErrorException(ex);
            }
        }
    }
}